package autoschedule.ui;

import alarm.*;
import autoteam.Local;
import autoteam.ui.AutoTeamFrame;

/*
NAME:  Juan C. Garcia ID# 56469701
CERTIFICATION: I certify that this work is my own and that
               none of it is the work of any other person.
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;

import java.io.IOException;
import java.text.DateFormatSymbols;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.event.TableModelEvent;

import controller.RSMSController;

/**
 *DaySelector is a bean for choosing a day.
 *
 * @author Kai Toedter
 * @version $LastChangedRevision: 107 $
 * @version $LastChangedDate: 2009-05-01 15:48:00 +0200 (Fr, 01 Mai 2009) $
 */

public class DaySelector extends JPanel implements ActionListener, KeyListener,
		FocusListener {
	int number = 0;
	
	private static final long serialVersionUID = 5876398337018781820L;

	protected JButton[] days;

	protected JButton[] weeks;

	protected JButton selectedDay;

	protected JPanel weekPanel;

	protected JPanel dayPanel;

	protected int day;

	protected Color oldDayBackgroundColor;

	protected Color selectedColor;

	protected Color sundayForeground;

	protected Color weekdayForeground;

	protected Color decorationBackgroundColor;

	protected String[] dayNames;

	protected Calendar calendar;

	protected Calendar today;

	protected Locale locale;

	protected boolean initialized;

	protected boolean weekOfYearVisible;

	protected boolean decorationBackgroundVisible = true;

	protected boolean decorationBordersVisible;

	protected boolean dayBordersVisible;

	private boolean alwaysFireDayProperty;

	protected Date minSelectableDate;

	protected Date maxSelectableDate;

	protected Date defaultMinSelectableDate;

	protected Date defaultMaxSelectableDate;

	protected int maxDayCharacters;
	
	private ArrayList[][] events;
	
	private AlarmSystem spam;
	
	//Frame to for pop up window
	private JFrame notices;
	
	ActionListener noticeListen;
	
	//Used to find Current User and Current Sport
	RSMSController control;
	
	/**
	 * Default JDayChooser constructor.
	 */
	public DaySelector() {
		this(false);
	}

	/**
	 * JDayChooser constructor.
	 *
	 * @param weekOfYearVisible
	 *            true, if the weeks of a year shall be shown
	 */
	public DaySelector(boolean weekOfYearVisible) {
		control = new RSMSController();
		spam = new AlarmSystem(control.getCurUser().getUsername()+"_"+control.getCurSport());
		setName("JDayChooser");
		setBackground(Color.white);
		this.weekOfYearVisible = weekOfYearVisible;
		locale = Locale.getDefault();
		days = new JButton[49];
		selectedDay = null;
		calendar = Calendar.getInstance(locale);
		today = (Calendar) calendar.clone();

		setLayout(new BorderLayout());

		dayPanel = new JPanel();
		dayPanel.setLayout(new GridLayout(7, 7));

		sundayForeground = new Color(164, 0, 0);
		weekdayForeground = new Color(0, 0, 0);
		
		

		// decorationBackgroundColor = new Color(194, 211, 252);
		// decorationBackgroundColor = new Color(206, 219, 246);
		// decorationBackgroundColor = new Color(210, 228, 238);
		
		// Background of The months and week numbers 
		decorationBackgroundColor = new Color(0,113,189);
		//decorationBackgroundColor = new Color(94,111,150);
		 

		for (int y = 0; y < 7; y++) 
		{
			for (int x = 0; x < 7; x++) 
			{
				int index = x + (7 * y);

				if (y == 0) 
				{
					// Create a button that doesn't react on clicks or focus
					// changes.
					// Thanks to Thomas Schaefer for the focus hint :)
					days[index] = new DecoratorButton();
				}
				else 
				{
					days[index] = new JButton("x");
					days[index].setBackground(oldDayBackgroundColor);					
					days[index].addActionListener(this);
					days[index].addKeyListener(this);
					days[index].addFocusListener(this);
				}

				days[index].setMargin(new Insets(0, 0, 0, 0));
				days[index].setFocusPainted(false);
				
				dayPanel.add(days[index]);
			}
		}

		weekPanel = new JPanel();
		weekPanel.setLayout(new GridLayout(7, 1));
		weeks = new JButton[7];

		for (int i = 0; i < 7; i++) {
			weeks[i] = new DecoratorButton();
			weeks[i].setMargin(new Insets(0, 0, 0, 0));
			weeks[i].setFocusPainted(false);
			weeks[i].setForeground(new Color(32, 32, 32));

			if (i != 0) {
				weeks[i].setText("0" + (i + 1));
			}

			weekPanel.add(weeks[i]);
		}

		Calendar tmpCalendar = Calendar.getInstance();
		tmpCalendar.set(1, 0, 1, 1, 1);
		defaultMinSelectableDate = tmpCalendar.getTime();
		minSelectableDate = defaultMinSelectableDate;
		tmpCalendar.set(9999, 0, 1, 1, 1);
		defaultMaxSelectableDate = tmpCalendar.getTime();
		maxSelectableDate = defaultMaxSelectableDate;

		init();

		setDay(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
		add(dayPanel, BorderLayout.CENTER);

		if (weekOfYearVisible) {
			add(weekPanel, BorderLayout.WEST);
		}
		initialized = true;
		updateUI();
		notices = new JFrame("Scheduled Notices");
		
	}

	/**
	 * Initilizes the locale specific names for the days of the week.
	 */
	public void init() {
		JButton testButton = new JButton();
		// Color for the Days not pressed
		oldDayBackgroundColor = new Color(158,203,225);
		// Color for the Days pressed
		selectedColor = new Color(213,233,240);

		Date date = calendar.getTime();
		calendar = Calendar.getInstance(locale);
		calendar.setTime(date);

		drawDayNames();
		//Creating Array List [Year][Month]
		events = new ArrayList[9999][12];
		

		
		helperPopulate(events);	
	}
	
	
	
	public void helperPopulate(ArrayList[][] temp)
	{
		List<Notice> pendings;
			
		pendings = spam.pendingNotices();
		
		for(Notice e: pendings)
		{
			if( events[e.getStartDate().getYear()][e.getStartDate().getMonth()] == null)
			{
				ArrayList notices = new ArrayList(31);
				notices.add(e);
				events[e.getStartDate().getYear()][e.getStartDate().getMonth()] = notices;
				//Testing how events is being filled
				//System.out.println("The notice is :"+ e.getMessage() + "during " + e.getStartDate().getDate());
				//System.out.println("The year going in is : "+ e.getDate().getYear());
				//System.out.println("The month going in is : "+ e.getDate().getMonth());
				//System.out.println("The day going into the notice is : " + e.getDate().getDate());
			}
			else
			{
				events[e.getStartDate().getYear()][e.getStartDate().getMonth()].add(e);
				//System.out.println("The notice(add) is :"+ e.getMessage() + "during " + e.getStartDate().getDate());
				
			}
		}
		drawDays();
	}
	
	//Testing Events information
	public void eventToString()
	{
		String h = "";
		int counter = 0;
		for (int i =0; i < 9999; i++)
		{
			for(int j = 0; j < 12; j++)
			{
				h += "\n " + events[i][j] + " ";
				if(events[i][j]!= null)
				{
					counter ++;
					System.out.print( counter);
				}
			}
		}
	}

	/**
	 * Draws the day names of the day columnes.
	 */
	private void drawDayNames() {
		int firstDayOfWeek = calendar.getFirstDayOfWeek();
		DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(locale);
		dayNames = dateFormatSymbols.getShortWeekdays();

		int day = firstDayOfWeek;

		for (int i = 0; i < 7; i++) {
			if (maxDayCharacters > 0 && maxDayCharacters < 5) {
				if (dayNames[day].length() >= maxDayCharacters) {
					dayNames[day] = dayNames[day]
							.substring(0, maxDayCharacters);
				}
			}

			days[i].setText(dayNames[day]);

			if (day == 1) {
				days[i].setForeground(sundayForeground);
			} else {
				days[i].setForeground(weekdayForeground);
			}

			if (day < 7) {
				day++;
			} else {
				day -= 6;
			}
		}
	}

	/**
	 * Initializes both day names and weeks of the year.
	 */
	protected void initDecorations() {
		for (int x = 0; x < 7; x++) {
			days[x].setContentAreaFilled(decorationBackgroundVisible);
			days[x].setBorderPainted(decorationBordersVisible);
			days[x].invalidate();
			days[x].repaint();
			weeks[x].setContentAreaFilled(decorationBackgroundVisible);
			weeks[x].setBorderPainted(decorationBordersVisible);
			weeks[x].invalidate();
			weeks[x].repaint();
		}
	}

	/**
	 * Hides and shows the week buttons.
	 */
	protected void drawWeeks() {
		Calendar tmpCalendar = (Calendar) calendar.clone();

		for (int i = 1; i < 7; i++) {
			tmpCalendar.set(Calendar.DAY_OF_MONTH, (i * 7) - 6);

			int week = tmpCalendar.get(Calendar.WEEK_OF_YEAR);
			String buttonText = Integer.toString(week);

			if (week < 10) {
				buttonText = "0" + buttonText;
			}

			weeks[i].setText(buttonText);

			if ((i == 5) || (i == 6)) {
				weeks[i].setVisible(days[i * 7].isVisible());
			}
		}
	}

	/**
	 * Hides and shows the day buttons.
	 */
	protected void drawDays() {
		
		
		Calendar tmpCalendar = (Calendar) calendar.clone();
		tmpCalendar.set(Calendar.HOUR_OF_DAY, 0);
		tmpCalendar.set(Calendar.MINUTE, 0);
		tmpCalendar.set(Calendar.SECOND, 0);
		tmpCalendar.set(Calendar.MILLISECOND, 0);
		
		
		Calendar minCal = Calendar.getInstance();
		minCal.setTime(minSelectableDate);
		minCal.set(Calendar.HOUR_OF_DAY, 0);
		minCal.set(Calendar.MINUTE, 0);
		minCal.set(Calendar.SECOND, 0);
		minCal.set(Calendar.MILLISECOND, 0);

		Calendar maxCal = Calendar.getInstance();
		maxCal.setTime(maxSelectableDate);
		maxCal.set(Calendar.HOUR_OF_DAY, 0);
		maxCal.set(Calendar.MINUTE, 0);
		maxCal.set(Calendar.SECOND, 0);
		maxCal.set(Calendar.MILLISECOND, 0);

		int firstDayOfWeek = tmpCalendar.getFirstDayOfWeek();
		tmpCalendar.set(Calendar.DAY_OF_MONTH, 1);
		int firstDay = tmpCalendar.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek;
		
		
		if (firstDay < 0) {
			firstDay += 7;
		}

		int i;

		for (i = 0; i < firstDay; i++) {
			days[i + 7].setVisible(false);
			days[i + 7].setText("");
		}
		
		
		tmpCalendar.add(Calendar.MONTH, 1);

		Date firstDayInNextMonth = tmpCalendar.getTime();
		
		tmpCalendar.add(Calendar.MONTH, -1);
		Date firstDayInMonth = tmpCalendar.getTime();
		
		//Testing the Year and Month of the map
		//System.out.println("The Year is : " + (tmpCalendar.getTime().getYear()+1900));
		//System.out.println("The Month is : " + (tmpCalendar.getTime().getMonth()+1));

		
		
		Date day = tmpCalendar.getTime();
		int n = 0;
		Color foregroundColor = getForeground();
		
		
		
		while (day.before(firstDayInNextMonth)) {
			days[i + n + 7].setText(Integer.toString(n + 1));
			days[i + n + 7].setIcon(new javax.swing.ImageIcon(""));

			days[i + n + 7].setVisible(true);
			if ((tmpCalendar.get(Calendar.DAY_OF_YEAR) == today
					.get(Calendar.DAY_OF_YEAR))
					&& (tmpCalendar.get(Calendar.YEAR) == today
							.get(Calendar.YEAR))) {
				days[i + n + 7].setForeground(sundayForeground);
			} else {
				days[i + n + 7].setForeground(foregroundColor);
			}

			if ((n + 1) == this.day) {
				days[i + n + 7].setBackground(selectedColor);
				selectedDay = days[i + n + 7];
			} else {
				days[i + n + 7].setBackground(oldDayBackgroundColor);
				days[i + n + 7].setBorderPainted(true);
			}

			if (tmpCalendar.before(minCal) || tmpCalendar.after(maxCal)) {
				days[i + n + 7].setEnabled(false);
			} else {
				days[i + n + 7].setEnabled(true);
			}

			n++;
			tmpCalendar.add(Calendar.DATE, 1);
			day = tmpCalendar.getTime();
		}
		
		for (int k = n + i + 7; k < 49; k++) {
			days[k].setVisible(false);
			days[k].setText("");
		}
		
		//The month was increased in the previous method
		tmpCalendar.add(Calendar.MONTH, -1);
	
		
		if(events[tmpCalendar.getTime().getYear()][tmpCalendar.getTime().getMonth()] != null)
		{
			int noticeSize = events[tmpCalendar.getTime().getYear()][tmpCalendar.getTime().getMonth()].size();
			// Testing how many Notices we have scheduled for that month
			//System.out.println("The are : "+ noticeSize + " notices for month #" + (tmpCalendar.getTime().getMonth()+1));
			
			ArrayList<Notice> temporary = new ArrayList<Notice>(noticeSize);
			temporary = events[tmpCalendar.getTime().getYear()][tmpCalendar.getTime().getMonth()];
			int[] notice_list = new int[noticeSize];
			for( int j = 0 ; j < noticeSize; j++ )
			{
				notice_list[j] = temporary.get(j).getStartDate().getDate();
//				System.out.println("The day is : " + temporary.get(j).getDate().getDate());
				// Color for game not pressed
				Color game = new Color(255,128,0);
				// Color for game when pressed
				Color lgame = new Color(255,179,102);
				if((temporary.get(j).getStartDate().getDate()) == this.day)
				{ 
					days[temporary.get(j).getStartDate().getDate()+ 6 + firstDayInMonth.getDay()].setBackground(lgame);
					//Testing The Scheduled Games
					//System.out.println("You have clicked on a schedule game");
				}
				else
				{
					days[temporary.get(j).getStartDate().getDate()+ 6 + firstDayInMonth.getDay()].setBackground(game);		
				}
				if(control.getCurSport().equals("Basketball"))
				{
					days[temporary.get(j).getStartDate().getDate()+ 6 + firstDayInMonth.getDay()].setIcon(new javax.swing.ImageIcon("./trunk/img/Basketball_16.png"));
				}
				else if(control.getCurSport().equals("Soccer"))
				{
					days[temporary.get(j).getStartDate().getDate()+ 6 + firstDayInMonth.getDay()].setIcon(new javax.swing.ImageIcon("./trunk/img/Soccer_16.png"));
				}
				else if(control.getCurSport().equals("Football"))
				{
					days[temporary.get(j).getStartDate().getDate()+ 6 + firstDayInMonth.getDay()].setIcon(new javax.swing.ImageIcon("./trunk/img/Football_16.png"));
				}
				else 
				{
					days[temporary.get(j).getStartDate().getDate()+ 6 + firstDayInMonth.getDay()].setIcon(new javax.swing.ImageIcon("./trunk/img/Baseball_16.png"));
				}
				//final Notice local = temporary.get(j);
				
			}
			for(int dayOfMonth = 1; dayOfMonth <= 31; dayOfMonth++)
			{
				// Maximum of 24 games + 24 notices that can be sent per day
				final Notice[] toSend = new Notice[48];
				int k = 0;
				int counter = 0;
				while(k < noticeSize)
				{
					//Adding All the Notices in the same in toSend[]
					if(temporary.get(k).getStartDate().getDate() == dayOfMonth)
					{
						toSend[counter] = temporary.get(k);
						counter++;						
					}
					k++;
				}
				final int noticesInDay = counter;
				//Add action Listener to days of month that have events scheduled
				//If counter is 0, then days[] does not get action listener
				if(counter != 0)
				{
					days[dayOfMonth + 6 + firstDayInMonth.getDay()].addActionListener(new ActionListener() 
					{
				        public void actionPerformed(ActionEvent e) 
				        {
							if(!notices.isVisible()) 
								showNotice(toSend,noticesInDay);
						}});
				}
			}
		}
		
		
		
		drawWeeks();
	}
	
	
	
	public void showNotice(Notice[] tempNotice, int toSchedule )
	{
		notices.setSize(500,500);
		JPanel panel = new JPanel();
		
		String[] columnNames = {"Times",
                				"Notices",
                				"Games"};
		Object[][] data = {
			    {" 1:00-2:00 am", "", ""},
			    {" 2:00-3:00 am", "", ""},
			    {" 3:00-4:00 am", "", ""},
			    {" 4:00-5:00 am", "", ""},
			    {" 5:00-6:00 am", "", ""},
			    {" 6:00-7:00 am", "", ""},
			    {" 7:00-8:00 am", "", ""},
			    {" 8:00-9:00 am", "", ""},
			    {" 9:00-10:00 am", "", ""},
			    {"10:00-11:00 am", "", ""},
			    {"11:00-12:00 am", "", ""},
			    {"12:00-1:00 pm", "", ""},
			    {" 1:00-2:00 pm", "", ""},
			    {" 2:00-3:00 pm", "", ""},
			    {" 3:00-4:00 pm", "", ""},
			    {" 4:00-5:00 pm", "", ""},
			    {" 5:00-6:00 pm", "", ""},
			    {" 6:00-7:00 pm", "", ""},
			    {" 7:00-8:00 pm", "", ""},
			    {" 8:00-9:00 pm", "", ""},
			    {" 9:00-10:00 pm", "", ""},
			    {"10:00-11:00 pm", "", ""},
			    {"11:00-12:00 pm", "", ""}};

		JTable noticeTable = new JTable(data, columnNames){
		// Set table not editable
			public boolean isCellEditable(int row, int column){   
		    return false;   
		  } 
		};
		
		JScrollPane pane = new JScrollPane(noticeTable);
		
		for(int i = 0; i < toSchedule; i++)
		{
			//System.out.println("The message is : "+ tempNotice[i].getMessage());
			int start = tempNotice[i].getStartDate().getHours();
			//System.out.println("Start is : "+ start);
		
			int length = tempNotice[i].getEndDate().getHours() - tempNotice[i].getStartDate().getHours();
			//System.out.println("Length is : " + length);
			
			for(int j = 0; j < length; j++)
			{
				//System.out.println("The Type of the notice is: " + tempNotice[i].getType());
				if(tempNotice[i].getType().equals((String) "game"))
				{
					noticeTable.setValueAt(tempNotice[i].getMessage(),start+j-1,2);
				}
				else
					noticeTable.setValueAt(tempNotice[i].getMessage(),start+j-1,1);
			}	
		}
		
		panel.add(pane);
		notices.setContentPane(panel);
		notices.setVisible(true);
	}
	


	/**
	 * Returns the locale.
	 *
	 * @return the locale value
	 *
	 * @see #setLocale
	 */
	public Locale getLocale() {
		return locale;
	}

	/**
	 * Sets the locale.
	 *
	 * @param locale
	 *            the new locale value
	 *
	 * @see #getLocale
	 */
	public void setLocale(Locale locale) {
		if (!initialized) {
			super.setLocale(locale);
		} else {
			this.locale = locale;
			super.setLocale(locale);
			init();
		}
	}

	/**
	 * Sets the day. This is a bound property.
	 *
	 * @param d
	 *            the day
	 *
	 * @see #getDay
	 */
	public void setDay(int d) {
		if (d < 1) {
			d = 1;
		}
		Calendar tmpCalendar = (Calendar) calendar.clone();
		tmpCalendar.set(Calendar.DAY_OF_MONTH, 1);
		tmpCalendar.add(Calendar.MONTH, 1);
		tmpCalendar.add(Calendar.DATE, -1);

		int maxDaysInMonth = tmpCalendar.get(Calendar.DATE);

		
		if (d > maxDaysInMonth) {
			d = maxDaysInMonth;
		}

		int oldDay = day;
		day = d;

//		if (selectedDay != null) {
//			selectedDay.setBackground(oldDayBackgroundColor);
//			selectedDay.repaint();
//		}
//
//		for (int i = 7; i < 49; i++) {
//			if (days[i].getText().equals(Integer.toString(day))) {
//				selectedDay = days[i];
//				selectedDay.setBackground(selectedColor);
//				break;
//			}
//		}

		if (alwaysFireDayProperty) {
			firePropertyChange("day", 0, day);
		} else {
			firePropertyChange("day", oldDay, day);
		}
	}

	/**
	 * this is needed for JDateChooser.
	 *
	 * @param alwaysFire
	 *            true, if day property shall be fired every time a day is
	 *            chosen.
	 */
	public void setAlwaysFireDayProperty(boolean alwaysFire) {
		alwaysFireDayProperty = alwaysFire;
	}

	/**
	 * Returns the selected day.
	 *
	 * @return the day value
	 *
	 * @see #setDay
	 */
	public int getDay() {
		return day;
	}

	/**
	 * Sets a specific month. This is needed for correct graphical
	 * representation of the days.
	 *
	 * @param month
	 *            the new month
	 */
	public void setMonth(int month) {
		calendar.set(Calendar.MONTH, month);
		int maxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

		int adjustedDay = day;
		if (day > maxDays) {
			adjustedDay = maxDays;
			setDay(adjustedDay);
		}
		for(int i = 7; i< 49; i++)
		{
			try
			{
				ActionListener[] listeners = days[i].getActionListeners();
				for ( int j = 0; j < listeners.length; j++)
				{
					days[i].removeActionListener(listeners[j]);
				}
				days[i].addActionListener(this);
			}
			
			catch(IndexOutOfBoundsException e)
			{
				//System.out.println("");
			}	
			
		}
		
		drawDays();

		
	}

	/**
	 * Sets a specific year. This is needed for correct graphical representation
	 * of the days.
	 *
	 * @param year
	 *            the new year
	 */
	public void setYear(int year) {
		calendar.set(Calendar.YEAR, year);
		for(int i = 7; i< 49; i++)
		{
			try
			{
				ActionListener[] listeners = days[i].getActionListeners();
				for ( int j = 0; j < listeners.length; j++)
				{
					days[i].removeActionListener(listeners[j]);
				}
				days[i].addActionListener(this);
			}
			
			catch(IndexOutOfBoundsException e)
			{
				//System.out.println("");
			}	
			
		}
		drawDays();
	}

	/**
	 * Sets a specific calendar. This is needed for correct graphical
	 * representation of the days.
	 *
	 * @param calendar
	 *            the new calendar
	 */
	public void setCalendar(Calendar calendar) {
		this.calendar = calendar;
		drawDays();
	}

	/**
	 * Sets the font property.
	 *
	 * @param font
	 *            the new font
	 */
	public void setFont(Font font) {
		if (days != null) {
			for (int i = 0; i < 49; i++) {
				days[i].setFont(font);
			}
		}
		if (weeks != null) {
			for (int i = 0; i < 7; i++) {
				weeks[i].setFont(font);
			}
		}
	}

	/**
	 * Sets the foregroundColor color.
	 *
	 * @param foreground
	 *            the new foregroundColor
	 */
	public void setForeground(Color foreground) {
		super.setForeground(foreground);

		if (days != null) {
			for (int i = 7; i < 49; i++) {
				days[i].setForeground(foreground);
			}

			drawDays();
		}
	}

	/**
	 * JDayChooser is the ActionListener for all day buttons.
	 *
	 * @param e
	 *            the ActionEvent
	 */
	public void actionPerformed(ActionEvent e) {
		JButton button = (JButton) e.getSource();
		String buttonText = button.getText();
		int day = new Integer(buttonText).intValue();
		setDay(day);
		drawDays();
	}

	/**
	 * JDayChooser is the FocusListener for all day buttons. (Added by Thomas
	 * Schaefer)
	 *
	 * @param e
	 *            the FocusEvent
	 */
	/*
	 * Code below commented out by Mark Brown on 24 Aug 2004. This code breaks
	 * the JDateChooser code by triggering the actionPerformed method on the
	 * next day button. This causes the date chosen to always be incremented by
	 * one day.
	 */
	public void focusGained(FocusEvent e) {
		// JButton button = (JButton) e.getSource();
		// String buttonText = button.getText();
		//
		// if ((buttonText != null) && !buttonText.equals("") &&
		// !e.isTemporary()) {
		// actionPerformed(new ActionEvent(e.getSource(), 0, null));
		// }
	}

	/**
	 * Does nothing.
	 *
	 * @param e
	 *            the FocusEvent
	 */
	public void focusLost(FocusEvent e) {
	}

	/**
	 * JDayChooser is the KeyListener for all day buttons. (Added by Thomas
	 * Schaefer and modified by Austin Moore)
	 *
	 * @param e
	 *            the KeyEvent
	 */
	public void keyPressed(KeyEvent e) {
		int offset = (e.getKeyCode() == KeyEvent.VK_UP) ? (-7) : ((e
				.getKeyCode() == KeyEvent.VK_DOWN) ? (+7)
				: ((e.getKeyCode() == KeyEvent.VK_LEFT) ? (-1) : ((e
						.getKeyCode() == KeyEvent.VK_RIGHT) ? (+1) : 0)));

		int newDay = getDay() + offset;

		if ((newDay >= 1)
				&& (newDay <= calendar.getMaximum(Calendar.DAY_OF_MONTH))) {
			setDay(newDay);
		}
		drawDays();
	}

	/**
	 * Does nothing.
	 *
	 * @param e
	 *            the KeyEvent
	 */
	public void keyTyped(KeyEvent e) {
	}

	/**
	 * Does nothing.
	 *
	 * @param e
	 *            the KeyEvent
	 */
	public void keyReleased(KeyEvent e) {
	}

	/**
	 * Enable or disable the JDayChooser.
	 *
	 * @param enabled
	 *            The new enabled value
	 */
	public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);

		for (short i = 0; i < days.length; i++) {
			if (days[i] != null) {
				days[i].setEnabled(enabled);
			}
		}

		for (short i = 0; i < weeks.length; i++) {
			if (weeks[i] != null) {
				weeks[i].setEnabled(enabled);
			}
		}
	}

	/**
	 * In some Countries it is often usefull to know in which week of the year a
	 * date is.
	 *
	 * @return boolean true, if the weeks of the year is shown
	 */
	public boolean isWeekOfYearVisible() {
		return weekOfYearVisible;
	}

	/**
	 * In some Countries it is often usefull to know in which week of the year a
	 * date is.
	 *
	 * @param weekOfYearVisible
	 *            true, if the weeks of the year shall be shown
	 */
	public void setWeekOfYearVisible(boolean weekOfYearVisible) {
		if (weekOfYearVisible == this.weekOfYearVisible) {
			return;
		} else if (weekOfYearVisible) {
			add(weekPanel, BorderLayout.WEST);
		} else {
			remove(weekPanel);
		}

		this.weekOfYearVisible = weekOfYearVisible;
		validate();
		dayPanel.validate();
	}

	/**
	 * Returns the day panel.
	 *
	 * @return the day panel
	 */
	public JPanel getDayPanel() {
		return dayPanel;
	}

	/**
	 * Returns the color of the decoration (day names and weeks).
	 *
	 * @return the color of the decoration (day names and weeks).
	 */
	public Color getDecorationBackgroundColor() {
		return decorationBackgroundColor;
	}

	/**
	 * Sets the background of days and weeks of year buttons.
	 *
	 * @param decorationBackgroundColor
	 *            The background to set
	 */
	public void setDecorationBackgroundColor(Color decorationBackgroundColor) {
		this.decorationBackgroundColor = decorationBackgroundColor;

		if (days != null) {
			for (int i = 0; i < 7; i++) {
				days[i].setBackground(decorationBackgroundColor);
			}
		}

		if (weeks != null) {
			for (int i = 0; i < 7; i++) {
				weeks[i].setBackground(decorationBackgroundColor);
			}
		}
	}

	/**
	 * Returns the Sunday foreground.
	 *
	 * @return Color the Sunday foreground.
	 */
	public Color getSundayForeground() {
		return sundayForeground;
	}

	/**
	 * Returns the weekday foreground.
	 *
	 * @return Color the weekday foreground.
	 */
	public Color getWeekdayForeground() {
		return weekdayForeground;
	}

	/**
	 * Sets the Sunday foreground.
	 *
	 * @param sundayForeground
	 *            The sundayForeground to set
	 */
	public void setSundayForeground(Color sundayForeground) {
		this.sundayForeground = sundayForeground;
		drawDayNames();
		drawDays();
	}

	/**
	 * Sets the weekday foreground.
	 *
	 * @param weekdayForeground
	 *            The weekdayForeground to set
	 */
	public void setWeekdayForeground(Color weekdayForeground) {
		this.weekdayForeground = weekdayForeground;
		drawDayNames();
		drawDays();
	}

	/**
	 * Requests that the selected day also have the focus.
	 */
	public void setFocus() {
		if (selectedDay != null) {
			this.selectedDay.requestFocus();
		}
	}

	/**
	 * The decoration background is the background color of the day titles and
	 * the weeks of the year.
	 *
	 * @return Returns true, if the decoration background is painted.
	 */
	public boolean isDecorationBackgroundVisible() {
		return decorationBackgroundVisible;
	}

	/**
	 * The decoration background is the background color of the day titles and
	 * the weeks of the year.
	 *
	 * @param decorationBackgroundVisible
	 *            true, if the decoration background shall be painted.
	 */
	public void setDecorationBackgroundVisible(
			boolean decorationBackgroundVisible) {
		this.decorationBackgroundVisible = decorationBackgroundVisible;
		initDecorations();
	}

	/**
	 * The decoration border is the button border of the day titles and the
	 * weeks of the year.
	 *
	 * @return Returns true, if the decoration border is painted.
	 */
	public boolean isDecorationBordersVisible() {
		return decorationBordersVisible;
	}

	public boolean isDayBordersVisible() {
		return dayBordersVisible;
	}

	/**
	 * The decoration border is the button border of the day titles and the
	 * weeks of the year.
	 *
	 * @param decorationBordersVisible
	 *            true, if the decoration border shall be painted.
	 */
	public void setDecorationBordersVisible(boolean decorationBordersVisible) {
		this.decorationBordersVisible = decorationBordersVisible;
		initDecorations();
	}

	public void setDayBordersVisible(boolean dayBordersVisible) {
		this.dayBordersVisible = dayBordersVisible;
		if (initialized) {
			for (int x = 7; x < 49; x++) 
			{
				days[x].setContentAreaFilled(true);
				days[x].setBorderPainted(dayBordersVisible);
			}
		}
	}

	/**
	 * Updates the UI and sets the day button preferences.
	 */
	public void updateUI() {
		super.updateUI();
		setFont(Font.decode("Dialog Plain 11"));

		if (weekPanel != null) {
			weekPanel.updateUI();
		}
		if (initialized) {
			setDayBordersVisible(true);
			setDecorationBackgroundVisible(true);
			setDecorationBordersVisible(false);
		}
	}

	/**
	 * Sets a valid date range for selectable dates. If max is before min, the
	 * default range with no limitation is set.
	 *
	 * @param min
	 *            the minimum selectable date or null (then the minimum date is
	 *            set to 01\01\0001)
	 * @param max
	 *            the maximum selectable date or null (then the maximum date is
	 *            set to 01\01\9999)
	 */
	public void setSelectableDateRange(Date min, Date max) {
		if (min == null) {
			minSelectableDate = defaultMinSelectableDate;
		} else {
			minSelectableDate = min;
		}
		if (max == null) {
			maxSelectableDate = defaultMaxSelectableDate;
		} else {
			maxSelectableDate = max;
		}
		if (maxSelectableDate.before(minSelectableDate)) {
			minSelectableDate = defaultMinSelectableDate;
			maxSelectableDate = defaultMaxSelectableDate;
		}
		drawDays();
	}

	/**
	 * Sets the maximum selectable date. If null, the date 01\01\9999 will be
	 * set instead.
	 *
	 * @param max
	 *            the maximum selectable date
	 *
	 * @return the maximum selectable date
	 */
	public Date setMaxSelectableDate(Date max) {
		if (max == null) {
			maxSelectableDate = defaultMaxSelectableDate;
		} else {
			maxSelectableDate = max;
		}
		drawDays();
		return maxSelectableDate;
	}

	/**
	 * Sets the minimum selectable date. If null, the date 01\01\0001 will be
	 * set instead.
	 *
	 * @param min
	 *            the minimum selectable date
	 *
	 * @return the minimum selectable date
	 */
	public Date setMinSelectableDate(Date min) {
		if (min == null) {
			minSelectableDate = defaultMinSelectableDate;
		} else {
			minSelectableDate = min;
		}
		drawDays();
		return minSelectableDate;
	}

	/**
	 * Gets the maximum selectable date.
	 *
	 * @return the maximum selectable date
	 */
	public Date getMaxSelectableDate() {
		return maxSelectableDate;
	}

	/**
	 * Gets the minimum selectable date.
	 *
	 * @return the minimum selectable date
	 */
	public Date getMinSelectableDate() {
		return minSelectableDate;
	}

	/**
	 * Gets the maximum number of characters of a day name or 0. If 0 is
	 * returned, dateFormatSymbols.getShortWeekdays() will be used.
	 *
	 * @return the maximum number of characters of a day name or 0.
	 */
	public int getMaxDayCharacters() {
		return maxDayCharacters;
	}

	/**
	 * Sets the maximum number of characters per day in the day bar. Valid
	 * values are 0-4. If set to 0, dateFormatSymbols.getShortWeekdays() will be
	 * used, otherwise theses strings will be reduced to the maximum number of
	 * characters.
	 *
	 * @param maxDayCharacters
	 *            the maximum number of characters of a day name.
	 */
	public void setMaxDayCharacters(int maxDayCharacters) {
		if (maxDayCharacters == this.maxDayCharacters) {
			return;
		}

		if (maxDayCharacters < 0 || maxDayCharacters > 4) {
			this.maxDayCharacters = 0;
		} else {
			this.maxDayCharacters = maxDayCharacters;
		}
		drawDayNames();
		drawDays();
		invalidate();
	}

	/**
	 * Creates a JFrame with a JDayChooser inside and can be used for testing.
	 *
	 * @param s
	 *            The command line arguments
	 */
	public static void main(String[] s) {
		JFrame frame = new JFrame("JDayChooser");
		DaySelector test = new DaySelector();
		frame.getContentPane().add(test);
		frame.pack();
		frame.setVisible(true);
	}

	class DecoratorButton extends JButton {
		private static final long serialVersionUID = -5306477668406547496L;

		public DecoratorButton() 
		{
			setBackground(decorationBackgroundColor);
			setContentAreaFilled(decorationBackgroundVisible);
			setBorderPainted(decorationBordersVisible);
		}
		
		

		public void addMouseListener(MouseListener l) 
		{
			
		}

		public boolean isFocusable() {
			return false;
		}

	};
	
	
	
}
